package kayao.server.network.message;

import java.net.InetAddress;
import java.net.UnknownHostException;
import kayao.common.Client;
import kayao.common.KayaoValues;
import kayao.common.NetworkUtils;
import kayao.server.DesktopServer;
import kayao.server.GameManager;

public class LoginMessage extends Message {

	protected String mAddress;
	protected byte []mDataReceived;
	
	protected LoginMessage(IncomingMessage m) {
		super(m.getIp(), 2, 2, 0);
		mDataReceived=m.getData();
		mAddress=m.getIp();
		createPacketData();
	}

	@Override
	public void createPacketData() {
		try
		{
			//If the server already knows the host, it resends the info
			Client c=DesktopServer.find(mAddress);
			if(c==null)
				c=createPlayer((int)mDataReceived[1]);

			//Calculating the size
			int size= calculateSizeAnswer(c.getId(),c.getTeam());
			mSendData= new byte[size];

			//Filling headers 
			fillHeadersLogin(mSendData,c.getId());
		
			//Filling teams
			int index=fillOwnTeam(13,mSendData,c);
			//index=fillRestTeams(index,data,c);
			
			//the position with 3 integers (X,Y,Z)
			index=fillInitialPositions(index,mSendData);
			//Finally the position of the flag 3 integers (X,Y,Z)
			fillMissionData(index,mSendData);

			
		}
		catch(Exception e)
		{
			//Basic treatment at the moment... show message and restart the reading
			System.out.println("LoginMessage Error: Error treating the login request: "+ e.getMessage());
			e.printStackTrace();
			//Some exceptions...
		}
	}
	/**
	 * It puts 3 int32 with the coords of the initial position of the car 
	 * @param index: The position to start to copy the values
	 * @param data: The place to store the values
	 */
	private int fillInitialPositions(int index, byte[] data) {
		//System.out.println("fillInitialPos data length: " + data.length+ " index: "+index);
		NetworkUtils.insertFloatToByteArray(data, index, 15);
		index+=4;
		NetworkUtils.insertFloatToByteArray(data, index, 0);
		index+=4;
		NetworkUtils.insertFloatToByteArray(data, index, 0);
		index+=4;

		return index;
	}
	
	private void fillMissionData(int index, byte[] data) 
	{
		byte []bytes=GameManager.getPositionBytes();
		System.arraycopy(bytes,0,data, index, bytes.length);
		index+=bytes.length;
		NetworkUtils.insertIntToByteArray(data, index, GameManager.getCurrentMissionId());
	}

	
	/**
	 * It fills the byte array with the values for the own team specified in the protocol
	 * @param index: the position to start to copy
	 * @param data the destiny array to copy to.
	 * @param c the client
	 * @return the next index to continue the copy
	 */
	private int fillOwnTeam(int index, byte[] data, Client c) {
		byte []value=new byte[4];
		data[index]=(byte)c.getTeam();
		index++;
		//number of team-mates (short)
		value=NetworkUtils.int32To2Bytes(DesktopServer.getTeams().get(c.getTeam()).size()-1);
		System.arraycopy(value, 0, data, index, 2);
		index+=2;
		
		//For his team we get ids, ips and name
		for(int i=0;i< DesktopServer.getTeams().get(c.getTeam()).size();i++)
		{
			//we skip itself
			if(DesktopServer.getTeams().get(c.getTeam()).get(i).getId()==c.getId())
				continue;

			value=DesktopServer.getTeams().get(c.getTeam()).get(i).getBytes();
			System.arraycopy(value, 1, data, index, (int)value[0]);
			index+=(int)value[0];
		}
		return index;
	}

	/**
	 * It fills the beginning of the byte array with some parameters 
	 * @param data: the array to copy to
	 * @param id: the id of the client
	 */
	private void fillHeadersLogin(byte[] data, int id) {
		//id msg
		data[0]=KayaoValues.PLAYING_REQUEST_REPLY_MESSAGE;
		//magic number
		byte []value=NetworkUtils.int32ToByte(KayaoValues.MAGIC_NUMBER);
		System.arraycopy(value, 0, data, 1, 4);
		//ID player
		value=NetworkUtils.int32ToByte(id);
		System.arraycopy(value, 0, data, 5, 4);
		// Players IP
		InetAddress clientIP;
		try {
			clientIP = InetAddress.getByName(DesktopServer.getClient(id).getIP());
			value=clientIP.getAddress();
			System.arraycopy(value, 0, data, 9, 4);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}

	/**
	 * It calculates the size of the byte array to copy the answer
	 * @param id ID of the client
	 * @param team Team of the client
	 * @return the bytes of the answer
	 */
	private int calculateSizeAnswer(int id, int team) {
		//Size= msg code +magic number+ id +client ip+team id+number of teammates + (X,Y,Z) ..
		int size= 28;//1+4+4+1+4+2+4+4+4
		size+=16; //flagmission
		//its team needs 9 bytes ( 4 for ID + 4 for ip + 1 name length) + name
		for(int i=0;i<DesktopServer.getTeams().get(team).size();i++)
		{
			if(DesktopServer.getTeams().get(team).get(i).getId()==id)
				continue;
			size+=(DesktopServer.getTeams().get(team).get(i).getName().length() + 9);
		}
		return size;
	}

	/**
	 * It manages the creation of a new player
	 * @param namelength: The length of the name
	 * @return the new client
	 */
	private Client createPlayer(int namelength) {
		String name="";
		for(int i=0; i<namelength;i++)
			name+=(char)mDataReceived[2+i];

		//It creates the client and it adds it to the list
		Client c=new Client(name,DesktopServer.getNextID(),mAddress,DesktopServer.getNextTeam());
		DesktopServer.addClient(c);
		System.out.println(DesktopServer.getTimestamp()+" [Server] NEW PLAYER \t Name: " + c.getName()+ " ID: "+ c.getId() +" IP: " +c.getIP()+ " Team: "+ c.getTeam());
		return c;

	}

	@Override
	public String type() 
	{
		return "Login";
	}

}
